package com.fingard.dsp.bank.directbank.kjtpay01.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.kjtpay.gateway.common.domain.VerifyResult;
import com.kjtpay.gateway.common.domain.base.RequestBase;
import com.kjtpay.gateway.common.domain.base.ResponseParameter;
import com.kjtpay.gateway.common.util.security.SecurityService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description TODO
 * @Author xtt
 * @Date $ $
 **/
public class RSAUtil {

    /**
     * 使用json字符串形式加密
     * @param signType
     * @param oriText
     * @param charset
     * @return
     */
    public static String encrypt(String signType, String oriText, String charset,String privateKey,String publicKey){
        //演示使用字符串形式加密
        SecurityService securityService = new SecurityService(privateKey,publicKey);
        if("RSA".equals(signType)){
            //RSA加密
            return securityService.encrypt(oriText, charset);
        }else if("ITRUS".equals(signType)){
            return securityService.encrypt(oriText, charset);
        }else{
            return null;
        }

    }

    /**
     * 解密
     * @param oriText
     * @param oriText
     * @param charset
     * @return
     */
    public static String decrypt(String oriText, String charset,String privateKey,String publicKey){
        //演示使用字符串形式加密
        SecurityService securityService = new SecurityService(privateKey,publicKey);
        //RSA加密
        return securityService.encrypt(oriText, charset);

    }

    /**
     * 商户验签
     * @param responseParameter
     * @return
     */
    public static VerifyResult verify(ResponseParameter responseParameter,String privateKey,String publicKey){

        if(null == responseParameter || StringUtils.isBlank(responseParameter.getSignType()) || StringUtils.isBlank(responseParameter.getCharset())){
            return null;
        }

        VerifyResult result = null;
        SecurityService securityService = new SecurityService(privateKey,publicKey);
        if("RSA".equals(responseParameter.getSignType())){
            //RSA验签
            result = securityService.verify(responseParameter, responseParameter.getSign(), responseParameter.getCharset());
        }else if("ITRUS".equals(responseParameter.getSignType())){
            result = securityService.verify(responseParameter, responseParameter.getSign(), responseParameter.getCharset());
        }

        return result;
    }

    /**
     * 商户签名
     * @param signData
     * @return
     */
    public static String sign(String signData,String privateKey,String publicKey){

        if(StringUtils.isNoneBlank(signData)){

            @SuppressWarnings("unchecked")
            Map<String,String> req = JSON.parseObject(signData, HashMap.class);

            String charset = req.get("charset");
            String signType = req.get("sign_type");
            if(StringUtils.isNoneBlank(charset) && StringUtils.isNoneBlank(signType)){

                String service = req.get("service");
                SecurityService securityService = new SecurityService(privateKey,publicKey);
                if("instant_trade".equals(service) || "ensure_trade".equals(service)){
                    //演示使用请求map方式签名
                    if("RSA".equals(signType)){
                        //RSA签名
                        return securityService.sign(req, charset);
                    }else if("ITRUS".equals(signType)){
                        return securityService.sign(req, charset);
                    }

                }else{

                    RequestBase requestBase = convertRequestBaseParm(req);

                    if("RSA".equals(signType)){
                        //RSA签名
                        return securityService.sign(requestBase, charset);
                    }else if("ITRUS".equals(signType)){
                        return securityService.sign(requestBase, charset);
                    }

                }

            }
        }

        return "请求参数不正确！";
    }

    /**
     * 商户验签
     * @param verifyData
     * @return
     * @throws UnsupportedEncodingException
     */
    public static boolean verify(String verifyData,String privateKey,String publicKey) throws UnsupportedEncodingException {

        boolean flag = false;
        if(StringUtils.isNoneBlank(verifyData)){

            VerifyResult result = null;

            Gson gson = new Gson();
            Map<String, String> responseParameter = new HashMap<String, String>();
            responseParameter = gson.fromJson(verifyData, responseParameter.getClass());

            String bizContent = responseParameter.get("biz_content")==null ? null : JSON.toJSONString(responseParameter.get("biz_content"));
            responseParameter.remove("biz_content");
            responseParameter.put("biz_content", bizContent);

            String signType = responseParameter.get("sign_type");
            String charset = responseParameter.get("charset");
            String sign = responseParameter.get("sign");
            SecurityService securityService = new SecurityService(privateKey,publicKey);
            if("RSA".equals(signType)){
                //RSA验签
                result = securityService.verify(responseParameter, sign, charset);
            }else if("ITRUS".equals(signType)){
                result = securityService.verify(responseParameter, sign, charset);
            }

            if(result!=null){
                if(result.isSuccess()){
                    flag = true;
                }else{
                    flag = false;
                }
            }else{
                flag = false;
            }

        }
        return flag;
    }

    /**
     * 转换参数
     * @param service
     * @param reqParm
     * @return
     */
    public JSONObject convertParm(String service, String reqParm){

        if("instant_trade".equals(service)){
            return convertInstantTradeParm(reqParm);

        }else if("ensure_trade".equals(service)){
            return convertInstantTradeParm(reqParm);

        }else if("trade_settle".equals(service)){
            List<String> fieldNameList = new ArrayList<String>();
            fieldNameList.add("royalty_info");
            return convertWithSpecialParm(reqParm, fieldNameList);

        }else if("entry_account_offline".equals(service)){
            return convertWithSpecialParm(reqParm, null);

        }else if("batch_bank_witholding".equals(service)){
            List<String> fieldNameList = new ArrayList<String>();
            fieldNameList.add("withholding_list");
            return convertWithSpecialParm(reqParm, fieldNameList);

        }else if("trade_bank_witholding".equals(service)){
            List<String> fieldNameList = new ArrayList<String>();
            fieldNameList.add("royalty_info");
            return convertWithSpecialParm(reqParm, fieldNameList);

        }else if("trade_close".equals(service)){
            return convertWithSpecialParm(reqParm, null);

        }else if("trade_query".equals(service)){
            return convertWithSpecialParm(reqParm, null);

        }else if("trade_refund".equals(service)){
            List<String> fieldNameList = new ArrayList<String>();
            fieldNameList.add("royalty_info");
            return convertWithSpecialParm(reqParm, fieldNameList);

        }else if("batch_transfer_account".equals(service)){
            List<String> fieldNameList = new ArrayList<String>();
            fieldNameList.add("transfer_list");
            return convertWithSpecialParm(reqParm, fieldNameList);

        }else if("transfer_to_account".equals(service)){
            return convertWithSpecialParm(reqParm, null);

        }else if("transfer_to_card".equals(service)){
            return convertWithSpecialParm(reqParm, null);

        }else if("batch_transfer_card".equals(service)){
            List<String> fieldNameList = new ArrayList<String>();
            fieldNameList.add("transfer_list");
            return convertWithSpecialParm(reqParm, fieldNameList);
        }
        return null;
    }
    /**
     * 转换给定参数名的参数，将给定参数的JSON字符串格式转换成JSON对象数组格式
     * @param reqParm
     * @param fieldNameList
     * @return
     */
    public JSONObject convertWithSpecialParm(String reqParm, List<String> fieldNameList){

        JSONObject reqJson = JSONObject.parseObject(reqParm);

        if(!CollectionUtils.isEmpty(fieldNameList)){

            for(String fieldName : fieldNameList){
                String fieldValue = reqJson.getString(fieldName);
                if(StringUtils.isNoneBlank(fieldValue)){
                    JSONArray fieldValueJSONArray = JSONArray.parseArray(fieldValue);
                    reqJson.put(fieldName, fieldValueJSONArray);
                }
            }

        }

        return reqJson;
    }


    /**
     * 转换即时到账参数
     * @param req
     * @return
     */
    public JSONObject convertInstantTradeParm(String req){
        JSONObject tradeReq = JSONObject.parseObject(req);
        //设置复杂属性
        //转换支付方式pay_method
        String pay_method = tradeReq.getString("pay_method");
        JSONObject payMethod = JSONObject.parseObject(pay_method);
        tradeReq.put("pay_method", payMethod);

        //转换终端信息域terminal_info
        String terminal_info = tradeReq.getString("terminal_info");
        JSONObject terminalInfo = JSONObject.parseObject(terminal_info);
        tradeReq.put("terminal_info", terminalInfo);
        //转换商户自定义域merchant_custom
        String merchant_custom = tradeReq.getString("merchant_custom");
        JSONObject merchantCustom = JSONObject.parseObject(merchant_custom);
        tradeReq.put("merchant_custom", merchantCustom);

        //转换交易信息trade_info
        String trade_info = tradeReq.getString("trade_info");

        if(StringUtils.isNoneBlank(trade_info)){
            JSONObject tradeInfo = JSONObject.parseObject(trade_info);


//			//转换交易扩展参数trade_ext
//			String trade_ext = tradeInfo.getString("trade_ext");
//			if(StringUtils.isNoneBlank(trade_ext)){
//				JSONObject tradeExt = JSONObject.parseObject(trade_ext);
//				tradeInfo.put("trade_ext", tradeExt);
//			}

            //转换分账列表royalty_info
            String royalty_info = tradeInfo.getString("royalty_info");
            if(StringUtils.isNoneBlank(royalty_info)){
                JSONArray royaltyInfos = JSONArray.parseArray(royalty_info);
                tradeInfo.put("royalty_info", royaltyInfos);
            }

            tradeReq.put("trade_info", tradeInfo);

            return tradeReq;
        }

        return null;
    }


    /**
     * 转换公共请求参数
     * @param req
     * @return
     */
    public static RequestBase convertRequestBaseParm(Map<String,String> req){
        if(!CollectionUtils.isEmpty(req)){
            RequestBase requestBase = new RequestBase();
            requestBase.setRequestNo(req.get("request_no"));
            requestBase.setService(req.get("service"));
            requestBase.setVersion(req.get("version"));
            requestBase.setPartnerId(req.get("partner_id"));
            requestBase.setCharset(req.get("charset"));
            requestBase.setSignType(req.get("sign_type"));
            requestBase.setSign(req.get("sign"));
            requestBase.setTimestamp(req.get("timestamp"));
            requestBase.setFormat(req.get("format"));
            requestBase.setBizContent(req.get("biz_content"));

            return requestBase;
        }
        return null;
    }

}
